﻿using System.ComponentModel.DataAnnotations;

namespace OperationPlugins.Validators.DataAnnotations
{
    public interface IUsePluginValidatorsAttributeSkipValidation
    {
        /// <summary>
        /// Decides whether the plugins validation should be skipped.
        /// </summary>
        /// <param name="value">The value to validate.</param>
        /// <param name="validationContext">Describes the context in which a data annotations validation check is performed.</param>
        /// <returns>True if the plugins validation should be skipped, otherwise false.</returns>
        bool SkipValidation(object value, ValidationContext validationContext);        
    }

    public interface IUsePluginValidatorsAttributeResolveOperation
    {
        /// <summary>
        /// Resolves the current operation.
        /// </summary>
        /// <remarks>
        /// The default value is <see cref="Operations.Any"/>.
        /// </remarks>
        /// <param name="value">The value to validate.</param>
        /// <param name="validationContext">Describes the context in which a data annotations validation check is performed.</param>
        /// <returns>The current operation.</returns>
        OperationId ResolveOperation(object value, ValidationContext validationContext);
    }

    public interface IUsePluginValidatorsAttributeResolveBranch
    {
        /// <summary>
        /// Resolves the current branch.
        /// </summary>
        /// <remarks>
        /// The default value is <see cref="Branches.Any"/>.
        /// </remarks>
        /// <param name="value">The value to validate.</param>
        /// <param name="validationContext">Describes the context in which a data annotations validation check is performed.</param>
        /// <returns>The current branch.</returns>
        BranchId ResolveBranch(object value, ValidationContext validationContext);
    }

    public interface IUsePluginValidatorsAttributeResolveOperationContextFactory
    {
        /// <summary>
        /// Resolves the operation context factory.
        /// </summary>
        /// <param name="value">The value to validate.</param>
        /// <param name="validationContext">Describes the context in which a data annotations validation check is performed.</param>
        /// <returns>The operation context factory.</returns>
        IOperationContextFactory ResolveOperationContextFactory(object value, ValidationContext validationContext);
    }

    public interface IUsePluginValidatorsAttributeValidate
    {
        /// <summary>
        /// Validates an object.
        /// </summary>
        /// <param name="value">The object to be validated.</param>
        /// <param name="operation">Identifies the current operation.</param>
        /// <param name="branch">Identifies the current branch.</param>
        /// <param name="contextFactory">The IOperationContextFactory to be used.</param>
        /// <returns>The ValidationResultMessageContainer object.</returns>
        ValidationResultMessageContainer Validate(object value, OperationId operation, BranchId branch, IOperationContextFactory contextFactory);    
    }

    public interface IUsePluginValidatorsAttributeAsDataAnnotationsValidationResult
    {
        /// <summary>
        /// Converts a <see cref="ValidationResultMessageContainer"/> object to <see cref="System.ComponentModel.DataAnnotations.ValidationResult"/> object.
        /// </summary>
        /// <param name="result">The <see cref="ValidationResultMessageContainer"/> object.</param>
        /// <returns>The <see cref="System.ComponentModel.DataAnnotations.ValidationResult"/> object.</returns>
        ValidationResult AsDataAnnotationsValidationResult(ValidationResultMessageContainer result);        
    }
}
